﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace A2.ERP.DAL
{
    /// <summary>
    ///  因为数据会话层已经定义了SaveChanges（）方法,这时数据库操作类中就不需要执行SaveChanges(),可以把所有的SavaChange()方法禁用
    ///  但是这时又面临着ef上下文实例创建的问题 DBsession创建了一次，这里又创建了一次，但是这里需要一个上下文对象，
    ///  
    /// 为了保持线程的唯一，创建一个工厂类DbContextFactory
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class BaseDAL<T> where T : class, new()
    {
        //一般直接将ef上下文实例,但是为了保障在请求过程中只创建一次ef上下文对象，
        //RaiseEntities DB = new RaiseEntities();

        //将其封装
        DbContext DB = DbContextFactory.CreateDbContext();

        public IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambada)
        {
            return DB.Set<T>().AsNoTracking().Where<T>(whereLambada);
        }

        public IQueryable<T> LoadPageEntities<orderT>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> wherelamdba, Expression<Func<T, orderT>> orderby, bool isAsc)
        {
            var temp = DB.Set<T>().AsNoTracking().Where(wherelamdba);
            totalCount = temp.Count();
            if (isAsc)//如果为true
            {
                temp = temp.OrderBy(orderby).Skip<T>((pageIndex - 1) * pageSize).Take<T>(pageSize);
            }
            else
            {
                temp = temp.OrderByDescending(orderby).Skip<T>((pageIndex - 1) * pageSize).Take<T>(pageSize);
            }
            return temp;
        }


        public bool DeleEntity(T entity)
        {
            DB.Entry<T>(entity).State = System.Data.EntityState.Deleted;

            return true;
        }

        public bool UpdateEntity(T entity, params Expression<Func<T, object>>[] props)
        {
            if (props == null || props.Length <= 0)
            {
                DB.Entry<T>(entity).State = System.Data.EntityState.Modified;
                return true;
            }

            DB.Set<T>().Attach(entity);
            var entry = DB.Entry(entity);
            foreach (var prop in props)
                entry.Property(prop).IsModified = true;

            return true;
        }


        public T AddEntity(T entity)
        {
            DB.Set<T>().Add(entity);
            //DB.SaveChanges();
            return entity;
        }

        public List<T> Procedures<T>(string sql, params SqlParameter[] ps)
        {
            return DB.Database.SqlQuery<T>(sql, ps).ToList();
        }

    }
}
